﻿#include "FRichTextEdit.h"
#include "ui_FRichTextEdit.h"

#include "../FSingleLineEditDialog/FSingleLineEditDialog.h"
#include "../FButtons/FInfoButton.h"
#include "FLineEdit.h"

#include <QTextCursor>
#include <QTextBlockFormat>
#include <QTextCharFormat>
#include <QFont>
#include <QColorDialog>
#include <QFileDialog>
#include <QInputDialog>
#include <QImageReader>
#include <QBuffer>
#include <QImage>
#include <QTextDocument>
#include <QDesktopServices>
#include <QApplication>
#include <QClipboard>
#include <QBrush>


FRichTextEdit::FRichTextEdit(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::FRichTextEdit)
    , m_alignGroup(new QButtonGroup(this))
{
    ui->setupUi(this);
    initView();

    FInfoButton _1;
    FLineEdit _2;
    setStyleSheet(_1.styleSheet() + _2.styleSheet());
}

FRichTextEdit::~FRichTextEdit()
{
    delete ui;
}

QString FRichTextEdit::toPlainText() const
{
    return ui->teBody->toPlainText();
}

QString FRichTextEdit::toHtml() const
{
    return ui->teBody->toHtml();
}

void FRichTextEdit::insertImage(const QImage &img)
{
    QImage scaled = scaledToContentWidth(img);

    // 将图片转为 Base64 字节
    QByteArray ba;
    QBuffer buffer(&ba);
    buffer.open(QIODevice::WriteOnly);
    img.save(&buffer, "PNG");      // 统一转成 PNG 格式
    buffer.close();

    // Base64 编码
    QString dataURL = "data:image/png;base64," + ba.toBase64();

    QTextCursor cur = ui->teBody->textCursor();
    QTextImageFormat fmt;
    fmt.setName(dataURL);
    fmt.setWidth(scaled.width());
    fmt.setHeight(scaled.height());

    cur.insertImage(fmt);
}

void FRichTextEdit::addWidget(QWidget *w)
{
    if (!w) return;
    ui->lineCustom->setVisible(true);
    ui->btnsLayout->addWidget(w);
}

void FRichTextEdit::initView()
{
    ui->lineCustom->setVisible(false);

    // 字体大小范围
    ui->cbFontSize->clear();
    for (int i = 6; i <= 72; i++) {
        ui->cbFontSize->addItem(QString::number(i));
    }

    // 对齐方式互斥
    m_alignGroup->addButton(ui->btnAlignLeft);
    m_alignGroup->addButton(ui->btnAlignCenter);
    m_alignGroup->addButton(ui->btnAlignRight);
    m_alignGroup->addButton(ui->btnAlignAuto);
    m_alignGroup->setExclusive(true);

    ui->teBody->setFontPointSize(11);
    ui->cbFontSize->setCurrentText("11");
    ui->btnColor->setColorIcon(Qt::transparent);
    ui->btnBgColor->setColorIcon(Qt::transparent);

    QTextCharFormat fmt;
    fmt.setBackground(Qt::transparent);
    applyCharFormatToSelection(fmt);

    // connect toolbar
    connect(ui->cbFontSize, &QComboBox::currentTextChanged, this, &FRichTextEdit::onFontSizeChanged);
    connect(ui->btnBold, &QAbstractButton::toggled, this, &FRichTextEdit::onBoldClicked);
    connect(ui->btnItalic, &QAbstractButton::toggled, this, &FRichTextEdit::onItalicClicked);
    connect(ui->btnUnderline, &QAbstractButton::toggled, this, &FRichTextEdit::onUnderlineClicked);

    connect(ui->btnAlignLeft, &QAbstractButton::clicked, this, &FRichTextEdit::onAlignLeftClicked);
    connect(ui->btnAlignCenter, &QAbstractButton::clicked, this, &FRichTextEdit::onAlignCenterClicked);
    connect(ui->btnAlignRight, &QAbstractButton::clicked, this, &FRichTextEdit::onAlignRightClicked);
    connect(ui->btnAlignAuto, &QAbstractButton::clicked, this, &FRichTextEdit::onAlignAutoClicked);

    connect(ui->btnTextRL, &QAbstractButton::toggled, this, &FRichTextEdit::onTextRLClicked);

    connect(ui->btnSuperScript, &QAbstractButton::toggled, this, &FRichTextEdit::onSuperScriptClicked);
    connect(ui->btnSubScript, &QAbstractButton::toggled, this, &FRichTextEdit::onSubScriptClicked);

    connect(ui->btnLink, &QAbstractButton::clicked, this, &FRichTextEdit::onInsertLink);
    connect(ui->btnPicture, &QAbstractButton::clicked, this, &FRichTextEdit::onInsertPicture);
    connect(ui->btnColor, &QAbstractButton::clicked, this, &FRichTextEdit::onColorClicked);
    connect(ui->btnBgColor, &QAbstractButton::clicked, this, &FRichTextEdit::onBgColorClicked);

    // 当光标移动或选择变化时，同步工具栏状态
    connect(ui->teBody, SIGNAL(cursorPositionChanged()), this, SLOT(onCursorPositionChanged()));

    // 初始同步
    onCursorPositionChanged();
}

QImage FRichTextEdit::scaledToContentWidth(const QImage &img)
{
    int maxWidth = ui->teBody->viewport()->width() - 20;
    maxWidth /= 2;

    if (img.width() > maxWidth)
        return img.scaledToWidth(maxWidth, Qt::SmoothTransformation);

    return img;
}

void FRichTextEdit::onFontSizeChanged(const QString &sizeText)
{
    bool ok = false;
    int pt = sizeText.toInt(&ok);
    if (!ok) return;

    QTextCharFormat fmt;
    fmt.setFontPointSize(pt);
    applyCharFormatToSelection(fmt);
}

void FRichTextEdit::onBoldClicked(bool checked)
{
    QTextCharFormat fmt;
    fmt.setFontWeight(checked ? QFont::Bold : QFont::Normal);
    applyCharFormatToSelection(fmt);
}

void FRichTextEdit::onItalicClicked(bool checked)
{
    QTextCharFormat fmt;
    fmt.setFontItalic(checked);
    applyCharFormatToSelection(fmt);
}

void FRichTextEdit::onUnderlineClicked(bool checked)
{
    QTextCharFormat fmt;
    fmt.setFontUnderline(checked);
    applyCharFormatToSelection(fmt);
}

void FRichTextEdit::onAlignLeftClicked()
{
    applyBlockFormatAlignment(Qt::AlignLeft);
}

void FRichTextEdit::onAlignCenterClicked()
{
    applyBlockFormatAlignment(Qt::AlignHCenter);
}

void FRichTextEdit::onAlignRightClicked()
{
    applyBlockFormatAlignment(Qt::AlignRight);
}

void FRichTextEdit::onAlignAutoClicked()
{
    // 这里把 Auto 当成两端对齐 (Justify)
    applyBlockFormatAlignment(Qt::AlignJustify);
}

void FRichTextEdit::onTextRLClicked(bool checked)
{
    // 将当前段落设置为 RTL 或 LTR
    QTextCursor cursor = ui->teBody->textCursor();
    QTextBlockFormat blockFmt = cursor.blockFormat();
    blockFmt.setLayoutDirection(checked ? Qt::RightToLeft : Qt::LeftToRight);
    cursor.mergeBlockFormat(blockFmt);
    ui->teBody->setTextCursor(cursor);
}

void FRichTextEdit::onSuperScriptClicked(bool checked)
{
    // 若开启上标，则关闭下标；反之亦然（互斥）
    if (checked && ui->btnSubScript->isChecked()) {
        ui->btnSubScript->setChecked(false);
    }

    QTextCharFormat fmt;
    fmt.setVerticalAlignment(checked ? QTextCharFormat::AlignSuperScript : QTextCharFormat::AlignNormal);
    applyCharFormatToSelection(fmt);
}

void FRichTextEdit::onSubScriptClicked(bool checked)
{
    if (checked && ui->btnSuperScript->isChecked()) {
        ui->btnSuperScript->setChecked(false);
    }

    QTextCharFormat fmt;
    fmt.setVerticalAlignment(checked ? QTextCharFormat::AlignSubScript : QTextCharFormat::AlignNormal);
    applyCharFormatToSelection(fmt);
}

void FRichTextEdit::onInsertLink()
{
    QTextCursor cursor = ui->teBody->textCursor();
    QString selectedText = cursor.selectedText();

    QStringList urlStrings = FSingleLineEditDialog::getStrings(this, "Insert Link",
                                                               QStringList() << tr("Text") << tr("Link"),
                                                        QStringList() << selectedText << "https://");

    if (urlStrings.isEmpty()) return;

    QTextCharFormat linkFmt;
    linkFmt.setAnchor(true);
    linkFmt.setAnchorHref(urlStrings[1]);
    linkFmt.setForeground(QBrush(Qt::blue));
    linkFmt.setFontUnderline(true);

    cursor.insertText(urlStrings[0], linkFmt);
}

void FRichTextEdit::onInsertPicture()
{
    QString path = QFileDialog::getOpenFileName(this, tr("Insert Picture"), QString(), tr("Images (*.png *.jpg *.jpeg *.bmp)"));
    if (path.isEmpty()) return;
    QImage img(path);
    if (img.isNull()) return;
    insertImage(img);
}

void FRichTextEdit::onColorClicked()
{
    QColor c = QColorDialog::getColor(ui->btnColor->iconColor(), this, tr("Select Text Color"), QColorDialog::ShowAlphaChannel);
    if (!c.isValid()) return;
    ui->btnColor->setColorIcon(c);

    QTextCharFormat fmt;
    fmt.setForeground(c);
    applyCharFormatToSelection(fmt);
}

void FRichTextEdit::onBgColorClicked()
{
    QColor c = QColorDialog::getColor(ui->btnBgColor->iconColor(), this, tr("Select Background Color"), QColorDialog::ShowAlphaChannel);
    if (!c.isValid()) return;
    ui->btnBgColor->setColorIcon(c);

    QTextCharFormat fmt;
    fmt.setBackground(c);
    applyCharFormatToSelection(fmt);
}

void FRichTextEdit::onCursorPositionChanged()
{
    QTextCharFormat fmt = currentCharFormat();
    QTextBlockFormat blockFmt = currentBlockFormat();

    // 同步字符格式按钮
    ui->btnBold->blockSignals(true);
    ui->btnItalic->blockSignals(true);
    ui->btnUnderline->blockSignals(true);
    ui->btnSuperScript->blockSignals(true);
    ui->btnSubScript->blockSignals(true);
    ui->cbFontSize->blockSignals(true);

    ui->btnBold->setChecked(fmt.fontWeight() == QFont::Bold);
    ui->btnItalic->setChecked(fmt.fontItalic());
    ui->btnUnderline->setChecked(fmt.fontUnderline());

    // 上标/下标
    QTextCharFormat::VerticalAlignment va = fmt.verticalAlignment();
    ui->btnSuperScript->setChecked(va == QTextCharFormat::AlignSuperScript);
    ui->btnSubScript->setChecked(va == QTextCharFormat::AlignSubScript);

    // 字体大小
    int pt = fmt.fontPointSize();
    if (pt <= 0) { // 没有设置时使用默认字体点大小
        pt = ui->teBody->fontPointSize();
    }
    QString ptText = QString::number(pt);
    int idx = ui->cbFontSize->findText(ptText);
    if (idx >= 0) {
        ui->cbFontSize->setCurrentIndex(idx);
    } else {
        // 若该大小不存在于下拉里，暂时插入显示
        int cur = ui->cbFontSize->currentIndex();
        ui->cbFontSize->setEditText(ptText);
        ui->cbFontSize->setCurrentIndex(cur);
    }

    // 对齐按钮
    ui->btnAlignLeft->blockSignals(true);
    ui->btnAlignCenter->blockSignals(true);
    ui->btnAlignRight->blockSignals(true);
    ui->btnAlignAuto->blockSignals(true);

    Qt::Alignment align = blockFmt.alignment();
    ui->btnAlignLeft->setChecked(align & Qt::AlignLeft);
    ui->btnAlignCenter->setChecked(align & Qt::AlignHCenter);
    ui->btnAlignRight->setChecked(align & Qt::AlignRight);
    ui->btnAlignAuto->setChecked(align & Qt::AlignJustify);

    // 文字颜色和背景颜色
    ui->btnColor->setColorIcon(fmt.foreground().color());
    ui->btnBgColor->setColorIcon(fmt.background().color());

    // 解除 blockSignals
    ui->btnBold->blockSignals(false);
    ui->btnItalic->blockSignals(false);
    ui->btnUnderline->blockSignals(false);
    ui->btnSuperScript->blockSignals(false);
    ui->btnSubScript->blockSignals(false);
    ui->cbFontSize->blockSignals(false);
    ui->btnAlignLeft->blockSignals(false);
    ui->btnAlignCenter->blockSignals(false);
    ui->btnAlignRight->blockSignals(false);
    ui->btnAlignAuto->blockSignals(false);
}

void FRichTextEdit::applyCharFormatToSelection(const QTextCharFormat &format)
{
    QTextCursor cursor = ui->teBody->textCursor();
    if (!cursor.hasSelection()) {
        // 合并到当前/下次输入的格式
        QTextCharFormat curFmt = ui->teBody->currentCharFormat();
        QTextCharFormat merged = curFmt;
        merged.merge(format);
        ui->teBody->setCurrentCharFormat(merged);
    } else {
        cursor.mergeCharFormat(format);
        ui->teBody->mergeCurrentCharFormat(format);
    }
}

void FRichTextEdit::applyBlockFormatAlignment(Qt::Alignment align)
{
    QTextCursor cursor = ui->teBody->textCursor();
    QTextBlockFormat blockFmt = cursor.blockFormat();
    blockFmt.setAlignment(align);
    cursor.mergeBlockFormat(blockFmt);
    ui->teBody->setTextCursor(cursor);
}

QTextCharFormat FRichTextEdit::currentCharFormat() const
{
    return ui->teBody->currentCharFormat();
}

QTextBlockFormat FRichTextEdit::currentBlockFormat() const
{
    return ui->teBody->textCursor().blockFormat();
}

void FRichTextEdit::on_btnCopyAsHtml_clicked()
{
    qApp->clipboard()->setText(toHtml());
}


void FRichTextEdit::on_teBody_anchorClicked(const QUrl &arg1)
{
    QDesktopServices::openUrl(arg1);
}
